import { _form } from './form.js'
import { _query, _content } from './dom.js'
import { renderContent } from './renderContent.js'
import { _type, getValue, setValue, propsSplitChar, snake2camel } from '../utils/index.js'
import { sortByOrder } from '../math/arraySort.js'
import { rerenderInspector } from './g2.js'
import { resetRoute } from './route.js'
import { isObject } from '../utils/index.js'
import { store } from '../store/index.js'
import {
    typesMap, keysOrder, defaultProps, multiLevelProps, selectFields,
    rotatableShape, layoutableShape
} from '../common/types.js'

// 属于多层级属性
const getMulitLevelPropRoot = (field) => {
    let flag = multiLevelProps.some(t => {
        let pref = `${t}${propsSplitChar}`
        return field.indexOf(pref) === 0
    })
    if (flag) {
        return field.split(propsSplitChar)[0]
    }
    return ""
}
// 保留属性
const keepProps = (obj, t) => {
    return ['number', 'string', 'boolean'].includes(_type(obj[t]))
}


// 深度覆盖
const deepAssign = (obj, obj2) => {
    Object.keys(obj).forEach(t => {
        if (obj2.hasOwnProperty(t)) {
            if (_type(obj[t]) === 'object' && _type(obj2[t]) === 'object') {
                Object.assign(obj[t], obj2[t])
            } else {
                obj[t] = obj2[t]
            }
        }
    })
    return obj
}

const _layoutable = (shapes) => {
    if (shapes.length !== 1) {
        return false
    }
    let shapeObj = shapes[0] || {}

    return layoutableShape.includes(shapeObj.shape)
}
const _push = (list, key) => {
    if (Array.isArray(key)) {
        key.forEach(t => _push(list, t))
    } else {
        !list.includes(key) && list.push(key)
    }
}

export const _inspector = (t) => {
    let { content, name } = t
    let { shapes, axis } = content
    // let layoutable = _layoutable(shapes)
    let shapeObj = shapes[0] || {}

    // 默认参数 旋转角度
    if (rotatableShape.includes(shapeObj.shape)) {
        if (shapeObj.a === undefined) {
            shapeObj.a = 0
        }
    }
    // 加颜色参数
    if (!shapeObj.color && !shapeObj.props
        && ['polygon', 'star', 'spiral', 'triangleLeaf'].includes(shapeObj.shape)
        && ['fractal', 'pathPoints', 'vertex'].some(t => shapeObj[t])) {
        shapeObj.color = 'colorCircle'
    }


    let keys = Object.keys(shapeObj).filter(t => keepProps(shapeObj, t));

    // 多层级属性
    multiLevelProps.forEach(t => {
        let obj = shapeObj[t]
        if (isObject(obj)) {
            let props = Object.keys(obj)
            if (props.length) {
                props.filter(u => keepProps(obj, u)).forEach(u => {
                    _push(keys, `${t}${propsSplitChar}${u}`)
                })
            } else {
                // 布尔型
                _push(keys, t)

            }

        } else if (obj) {
            // 字符
            _push(keys, t)


        }
    })

    // if (layoutable) {
    //     // 坐标轴
    //     _push(keys, ['axis', 'layout'])
    // }




    keys = sortByOrder(keys, keysOrder)

    let rerender = (model) => {
        console.log(model,Object.keys(model).length)
        let newModel = {}
        Object.keys(model).forEach(t => setValue(newModel, t, model[t]))
        let shapes = t.content.shapes.filter(t => model.shape === t.shape)
        shapes.forEach(t => deepAssign(t, newModel))
        console.log(newModel)
        // let layoutable = _layoutable(shapes)

        // if (layoutable) {
        // 坐标轴
        t.content.axis = newModel.axis 
        // ? null : {
        //     shape: newModel.axis,
        //     grid: {}
        // }

        // 排版
        t.content.layout = newModel.layout  //? null : newModel.layout
        // }

        // 画图
        console.log(t)
        let { content } = renderContent(t)
        let viewer = _query(".screen-viewer")
        let panel = _query(`.panel[name="${name}"]`, viewer)
        _content(panel, content)

        // 输入输出参数
        rerenderInspector(t, ['grammar', 'graphic'])
    }

    let formData = {
        fields: keys.map(field => {
            let value = field === 'axis' ? getValue(axis, field) : getValue(shapeObj, field)
            let type = _type(value)

            // 空对象转布尔
            if (type === 'object' && Object.keys(value).length === 0) {
                type = 'checkbox'
                value = true
            }


            let item = {
                ...defaultProps.find(t => t.field === field),
                field,
                label: field,
                value,
                type,
                disabled: /([a-z]+_)?shape$/.test(field),
            };
            let group = getMulitLevelPropRoot(field)
            if (group) {
                Object.assign(item, {
                    group,
                    label: field.replace(new RegExp(`${group}_`), "")
                })
            }


            // 下拉选项            
            selectFields.forEach(t => {
                let reg = new RegExp(`([a-z]+_)?${t}$`)
                if (reg.test(field)) { //field === t
                    let types
                    if (typesMap[`${t}Types`]) {
                        types = typesMap[`${t}Types`] || []
                    }
                    else if (field.indexOf('_') >= 0) {
                        types = typesMap[`${snake2camel(field)}s`] || []
                    }

                    if (Array.isArray(types)) {
                        item.options = types.map(t => {
                            return {
                                label: t,
                                value: t
                            }
                        })
                        item.type = 'select'
                    }

                }
            })
            return item
        }),
        op: [{
            type: 'btn',
            text: 'rerender',
            className: 'success',
            click: (e, { model }) => {
                rerender(model)

            }
        }]
    }
    if (!store.isH5) {
        // 暂不支持h5中reset
        formData.op.push({
            type: 'btn',
            text: 'reset',
            className: 'gray',
            click: () => {
                resetRoute()
            }
        })
    }
    return _form(formData)
}